from manimlib import *

class S2C(Scene):
    def construct(self):
        square = Square()
        square.set_fill(RED, .5)
        square.rotate(45*DEGREES)
        self.play(ShowCreation(square))
        self.play(DrawBorderThenFill(square))
        
        circle = Circle()
        circle.set_fill(BLUE, .5)
        self.play(Transform(square, circle))


class MakingSquare(Scene):
    def construct(self):
        sq = VMobject()
        points = [
            [1,1,0],
            [1,-1,0],
            [-1,-1,0],
            [-1,1,0],
        ]
        dots = VGroup(*[Dot(p) for p in points])
        self.add(dots)

        sq.set_points_as_corners(points)
        self.play(ShowCreation(sq), run_time=2)
        sq.add_points_as_corners([points[0]])
        sq.make_smooth()
        # .set_points_as_corners  .add_points_as_corners 添加点
        # .make_smooth()  .set_points_smoothly()  贝塞尔曲线

# manim 的画布默认是8*14.2，原点在画布重心，x轴左负右正，y轴下负上正。
# 对图像可以使用下面方式让图像在画布中标定位置与转换
# move_to - 移动到指定位置， 如 move_to(4*LEFT), 其中 LEFT = (-1,0,0)
# shift - 相对当前位置移动指定距离， 如 shift(UP+2*RIGHT)
# to_edge - 移动到边缘, 如 to_edge(DOWN, buff=1), buff为边距距离
# to_corner - 移动到角, 如 to_corner(UL, buff=0.25)
# scale - 缩放, 如 scale(2)
# rotate - 旋转, 如 rotate(PI/4)

# manim提供下面方法获取对象的属性
# get_center() - 获取中心点坐标
# get_left() - 获取左坐标
# get_right() - 获取右坐标
# get_top() - 获取上坐标
# get_bottom() - 获取下坐标

# get_width() - 获取宽度
# get_height() - 获取高度
# get_x() - 获取x坐标
# get_y() - 获取y坐标
# get_z() - 获取z坐标
# get_width() - 获取宽度
# get_height() - 获取高度
# get_corner() - 获取指定角坐标

# manim 预定义动画
# ShowCreation - 显示，如 ShowCreation(square)
# FadeOut - 消失，如 FadeOut(square)
# FadeIn - 显示，如 FadeIn(square)
# DrawBorderThenFill - 绘边填充，如 DrawBorderThenFill(square)
# Uncreate - 删除，如 Uncreate(square)

class DynamismToObject(Scene):
    def construct(self):
        sq = Square()
        sq.set_fill(TEAL, opacity=0.5)
        sq.move_to(2.5*LEFT)

        circle = Circle()
        circle.set_fill(RED, opacity=0.5)

        self.play(DrawBorderThenFill(sq))
        self.play(sq.animate.move_to(ORIGIN))
        # or self.play(sq.animate.shift(2.5*RIGHT))
        self.play(sq.animate.rotate(45*DEGREES))
        self.play(sq.animate.scale(2))

        self.play(sq.animate.become(circle))

class UpdateTemplate(Scene):
    def construct(self):
        sq = Square().set_fill(TEAL, opacity=0.5)
        sq.to_edge(LEFT, buff=1)
        sq.rotate(45*DEGREES)

        def update_square(s):
            s.shift(0.05*RIGHT)
            s.rotate(-2*DEGREES)

        self.play(ShowCreation(sq))
        sq.add_updater(update_square)
        self.wait(5)
        # self.play(UpdateFromAlphaFunc(sq, update_square), run_time=2)

class UpdateTemplate2(Scene):
    def construct(self):
        sq = Square().set_fill(TEAL, opacity=0.5)
        sq.to_edge(LEFT, buff=1)
        sq.rotate(45*DEGREES)

        circle = Circle().set_fill(RED, opacity=0.5) #
        circle.next_to(sq, DOWN, buff=0.5) #

        def update_square(s):
            s.shift(0.05*RIGHT)
            s.rotate(-2*DEGREES)

        self.play(ShowCreation(sq), FadeIn(circle)) #
        sq.add_updater(update_square)
        circle.add_updater(lambda c: c.next_to(sq, DOWN, buff=0.5)) #
        self.wait(5)
        

class UpdateTemplate3 (Scene):
    def construct(self):
        sq = Square().set_fill(TEAL, opacity=0.5)
        sq.to_edge(LEFT, buff=1)
        sq.rotate(45*DEGREES)

        circle = Circle().set_fill(RED, opacity=0.5)
        circle.next_to(sq, DOWN, buff=0.5)

        def update_square(s):
            s.shift(0.05*RIGHT)
            s.set_width(abs(2*np.sin(self.time))) #

        self.play(ShowCreation(sq), FadeIn(circle))
        sq.add_updater(update_square)
        circle.add_updater(lambda c: c.next_to(sq, DOWN, buff=0.5))
        circle.f_always.set_width(sq.get_width) #
        self.wait(5)
        

class BouncingBall(Scene):
    def construct(self):
        w, h = 12, 6
        box = Rectangle(width=w, height=h)
        box.set_stroke(width=8)

        ball = Dot(radius=.15)
        ball.vx, ball.vy = .05, .05 # x,y 轴的移动速度

        def update_ball(c):
            rp = c.get_right()[0]
            lp = c.get_left()[0]
            tp = c.get_top()[1]
            bp = c.get_bottom()[1]

            if rp >= w/2 or lp <= -w/2:
                c.vx *= -1
            if tp > h/2 or bp < -h/2:
                c.vy *= -1
            
            c.shift(c.vx*RIGHT+c.vy*UP)
        
        self.play(ShowCreation(ball), ShowCreation(box))
        ball.add_updater(update_ball)
        self.wait(5)

class RosePattern(VMobject):
    def __init__(self, radius:float=2, k:float=3, **kwargs):
        super().__init__(**kwargs)
        self.radius = radius
        self.k = k 

        step_size = .05
        theta = np.arange(0, TAU+step_size, step_size)

        points = [
            [
                radius*np.cos(k*t)*np.cos(t),
                radius*np.cos(k*t)*np.sin(t),
                0
            ]for t in theta
        ]

        self.set_points_smoothly(points)

class ShowingRosePattern(Scene):
    def construct(self):
        cs = [BLUE, WHITE, BLUE]
        rose = RosePattern(k = 10)
        rose.set_color_by_gradient(*cs)
        self.play(ShowCreation(rose), run_time=5)
        self.wait()

def get_rose_pattern(k:float, color:list = [BLUE, WHITE, BLUE]):
    return RosePattern(k=k).set_color_by_gradient(*color)

class AnimatingWithUpdateFunc(Scene):
    def construct(self) :
        rose = get_rose_pattern(k=0)
        rose.k = 0

        self.play(ShowCreation(rose))

        def update_rose(pat, dt):
            pat.k += dt
            new_pat = get_rose_pattern(k=pat.k)
            pat.become(new_pat)

        rose.add_updater(update_rose)
        self.wait(10)


class AnimatingWithValueTracker(Scene):
    def construct(self) :
        track_k = ValueTracker(0)
        rose = get_rose_pattern(k=track_k.get_value())

        self.play(ShowCreation(rose))

        def update_rose(pat):
            new_pat = get_rose_pattern(k=track_k.get_value())
            pat.become(new_pat)
        rose.add_updater(update_rose)
        self.play(
            track_k.animate.set_value(10),
            run_time=5
        )

        
class AnimatingWithValueTracker2(Scene):
    def construct(self) :
        track_k = ValueTracker(0)
        rose = get_rose_pattern(k=track_k.get_value())

        self.play(ShowCreation(rose))

        self.play(
            UpdateFromFunc(
                rose, lambda pat:pat.become(
                    get_rose_pattern(k=track_k.get_value())
                )
            ),
            track_k.animate.set_value(10),
            run_time=5
        )
        
class AnimatingWithForLoop(Scene):
    def construct(self) :
        rose = get_rose_pattern(k=0)
        self.play(ShowCreation(rose))
        k_increment = .01

        for k in np.arange(0, 10, k_increment) :
            self.play(rose.animate.become(get_rose_pattern(k=k)),
                      run_time = k_increment)

class RosePatternWithParametricCurve(ParametricCurve) :
    def __init__(self, radius=2, k = 10, theta_range=TAU, **kwargs) :
        self.radius = radius
        self.k = k 
        step_size = .05 


        
        super.__init__(
            t_func = lambda t:
            [
                radius * np.cos(k * t).np.cos(t),
                radius * np.cos(k * t).np.sin(t),
                0
            ],
            t_range=(0, theta_range+step_size, step_size)
            **kwargs
        )

class ParametricSinCurve(Scene):
    def construct(self):
        sin_curve = ParametricCurve(
            t_func=lambda t: [t, np.sin(t),0],t_range=[-PI,PI,.1]
        )
        sin_curve.set_color(YELLOW)
        self.play(ShowCreation(sin_curve))

class ParametricCurveExample(Scene):
    def construct(self):
        step_func = ParametricCurve(
            lambda t: [t, 0 if t<0 else 1, 0],
            discontinuities=[0],
            epsilon=0
        )
        self.play(ShowCreation(step_func))
        # sin_curve = FunctionGraph(np.sin)
        # cos_curve = FunctionGraph(np.cos)
        # parabola = FunctionGraph(lambda x: x**2)
        # cubic = FunctionGraph(lambda x: x**3)
        # relu = FunctionGraph(lambda x: max(0,x))

# 坐标系 - 包含轴(Axes)与数(NumberPlane)
# x_range: RangeSpecifier = (-8, 8, 1), x 轴的范围与步长
# color: ManimColor = GREY_B,
# stroke_width: float = 2.0,
# # How big is one one unit of this number line in terms of absolute spacial distance
# unit_size: float = 1.0,
# width: Optional[float] = None, # 坐标轴的宽度
# include_ticks: bool = True, # 添加刻度
# tick_size: float = 0.1,
# longer_tick_multiple: float = 1.5,
# tick_offset: float = 0.0,
# # Change name
# big_tick_spacing: Optional[float] = None,
# big_tick_numbers: list[float] = [],
# include_numbers: bool = False,  # 添加数字
# line_to_number_direction: Vect3 = DOWN,
# line_to_number_buff: float = MED_SMALL_BUFF,
# include_tip: bool = False,  # 添加箭头
# tip_config: dict = dict(
#     width=0.25,
#     length=0.25,
# ),
# decimal_number_config: dict = dict(  # 添加数字的格式
#     num_decimal_places=0,
#     font_size=36,
# ),
# numbers_to_exclude: list | None = None, # 指出不标记的数字

# .n2p(-6) -> (-3.0, 0.0, 0.0) # 将数轴上的点转换为画布坐标
# .p2n([-3.0, 0.0, 0.0]) -> -6.0  # 将画布坐标转换为数轴上的点
# .get_h_line(.c2p(-4,1)) # 坐标轴(-4,1)点的水平线
# .get_v_line(.c2p(-4,1)) # 坐标轴(-4,1)点的垂直线
# .get_v_line((-4.0, .8, 0.0)) # 如果知道场景中点的坐标，也可以直接传入坐标

# # 轴配置
#     axis_config: x,y 轴共同的配置
#     x_axis_config: x 轴的配置
#     y_axis_config: y 轴的配置 
class IntroToAxes(Scene):
    def construct(self) -> None:
        axes = Axes(
            x_range=[-5, 5, 1],
            y_range=[-3, 3, 1],
            axis_config=dict(include_tip=True)
        )
        axes.add_coordinate_labels()
        axes_labels = axes.get_axis_labels()
        self.play(ShowCreation(axes), Write(axes_labels))

        sin_curve = axes.get_graph(lambda t:np.sin(t))
        sin_curve.set_color(YELLOW)
        self.play(ShowCreation(sin_curve))

        cos_curve = axes.get_graph(np.cos)
        cos_curve.set_color(YELLOW)
        self.play(ShowCreation(cos_curve))


# group 组可以用于多个图形的排布与统一属性设置
class GroupingOjbect(Scene):
    def construct(self):
        circle = Circle()
        square = Square()
        hexagon = RegularPolygon(6)
        # star = Star(5).scale(.7)

        shapes = VMobject()
        shapes.add(circle, square, hexagon) #, star 
        # shapes = VGrop(circle, square, hexagon)
        # 组(VGrop)与子(Submobjects)
        # shapes.arrage(RIGHT， buff=2) # 水平排列
        # shapes.arrage(UP, buff=2) # 垂直排列
        # shapes.arrage(OUT, buff=2) # Z轴排列
        # shapes.arrage_in_grid(2,2) # 表格排序
        shapes.scale(.75)
        shapes.set_stroke(WHITE)


class DistanceTimeGraph(Scene):
    def construct(self):
        axes = Axes(
            x_range=[0, 7, 1],
            y_range=[0, 25, 1],
            height=6,
            axis_config=dict(include_tip=True)
        )
        axes.add_coordinate_labels()
        axes_labels = axes.get_axis_labels('t', 'x(t)')
        self.play(ShowCreation(axes), Write(axes_labels))

        dist_graph = axes.get_graph(
            function=lambda t:t**2 if t < 3 else 6*t - 9,
            x_range = [0, 5]
        ).set_color(BLUE)
        self.play(ShowCreation(dist_graph))

        tangent = axes.get_tangent_line(2.5, dist_graph)
        self.play(ShowCreation(tangent))

        vel_graph = axes.get_graph(
            lambda t:2*t if t < 3 else 6,
            x_range=(0, 5)
        ).set_color(RED)
        self.play(ShowCreation(vel_graph))
    
        dist_label = axes.get_graph_label(dist_graph, 'x(t)')
        vel_label = axes.get_graph_label(vel_graph, 'v(t)')
        self.play(Write(dist_label), Write(vel_label), FadeOut(axes_labels[1]))

        def get_slop_of_tangent(t, graph):
            p0 = graph.get_function()(t)
            p1 = graph.get_function()(t + EPSILON)
            return np.tan(angle_of_vector([EPSILON, p1-p0]))
        
        area = axes.get_area_under_graph(
            graph=vel_graph, 
            x_range=[2,4],
            fill_color=RED # fill_opacity=0.5
        )
        self.play(ShowCreation(area))

        # 扩展 
        # PMobject 
        # ImageMobject
        # Parametric Curves
        # SVGMobject

        # x = 1.5cos5 - cos(10t)
        # y = 1.5sint-sin(10t)

        # x = sin(3t+PI/2)
        # y = sin(2t)

        # x = cost/(1+(sint)^2)
        # y = sint/(1+(sint)^2)

        # x = sin(3t)-2sin(4t)
        # y = cos(3t)+2cos(4t)

        # x = sqrt(t)cost
        # y = sqrt(t)sint

# 目录结构
# manimgl --config 
# manim/
#   manimlib/
#       animation/
#       ...
#       default_config.yml
#       window.py
#   project/
#       code.py
#       custom_config.yml
#   custom_config.yml

# 图片
class ImageExample(Scene):
    def construct(self):
        img = ImageMobject('car')
        img.set_width(4)
        self.play(FadeIn(img))

        img.move_to(2*RIGHT)
        img.rotate(45*DEGREES)
        img.scale(.5)

# SVG 可对图像单元进行操作

# 文本生成 
# StringMobject(SVGMobject, ABC)
#   Tex: LaTex 格式-> 渲染为SVG
#   MarkupText: 渲染为正常文字
#       PangoMarkup: 类似与html语言
#       sub: Text(普通文本), Code(使用 ligatures 展示代码) 
#   -- Tex 数学表达式或者方程式
#   -- TexText latex富格式的文本
#   -- 显示普通文本
class MarkupTextExample(Scene):
    def construct(self):
        mtext = VGroup(
            MarkupText('<span>This is MarkupText</span>.'),
            MarkupText('This is <i>italic</i>.'),
            MarkupText('And this is <b>bold</b>.')
        ).arrange(DOWN, buff=.5)

        self.play(Write(mtext))
        self.play(FadeOut(mtext))

        eq = Tex(
            r'R_{\mu\nu} - {1 \over 2} Rg_{\mu\nu} + \Lambda g_{\mu\nu} = {8 \pi G \over c^4}T_{\mu\nu}',
            tex_to_color_map={
                'G':PINK # 字符级 选择功能
            },
            isolate=[r'R_{\mu\nu}',r'\Lambda'], # 定义隔离字符
        )
        eq[0].set_color(TEAL)
        eq[r'\Lambda'].set_color(BLUE) 
        eq.set_color_by_gradient(RED, PINK, YELLOW, BLUE) #设置颜色渐变
        self.add(eq)

        Text('This example is written in font \'Consolas\'.', font='Consolas')
        Text('With the help of Text class, we can assign '
             'different\n\ncolors to different words.')
        Text('for example: \n\nThis is Yellow color,\n\nand'
             'this shold render as Blue color.',
             t2c={'Yellow':YELLOW,'Blue':BLUE},
             )
        Text(
            'Not only colors, but it also changes the style '
            'of the words.\n\nThis is italic, and this is Bold',
            t2s={'italic':ITALIC},
            t2w={'Bold':BOLD},
        )
        Text(
            'Even we can write different words with different fonts like:\n\n'
            'Consolas, Arial, Cambria, Gabriola',
            t2f={
                'Consolas':'Consolas',
                'Arial':'Arial',
                'Cambria':'Cambria',
                'Gabriola':'Gabriola',
            }
        )

# 3D视角调整
# self.frame.set_euler_angles(theta, phi, gamma) 
#   theta - y轴旋转  
#   phi - x轴旋转 
#   gamma - z轴旋转
# self.frame.reorient(theta, phi, gamma) # 角度

class MakingSpiral(Scene):
    def construct(self):
        spiral = ParametricCurve(
            t_func=lambda t:[
                np.sin(t), t/7, np.cos(t)
            ],
            t_range=[-2*TAU, 2*TAU,1]
        )
        print('TAU:', TAU)
        self.play(Write(spiral))

# 3d 图形简化计算方法
# Euler's Method
# *Runge-Kutta Method         # scipy.integrate.solve_ivp
# Adams Beshforth Method
# BDF
# Gear's Method
# Finite Difference Method
# Jacobian Method
# *LSODA
# Shooting Method
# Gauss - Seidel Method
# Spectral Method

class LorenzAttractorScene(Scene):
    pos = np.array([.1, 0, 0]) # 初始化位置
    num_points = int(1e4)
    sim_time = 50 # 模拟时间
    constants = (10, 28, 8/3)

    def construct(self):
        self.frame.reorient(45, 60, 0)

        lorenz_curve = self.get_lorenz_curve()
        lorenz_curve.set_width(FRAME_WIDTH/2.5).center()
        lorenz_curve.set_color_by_gradient(DARK_BROWN, WHITE, DARK_BROWN)
        self.play(
            ShowCreation(lorenz_curve),
            run_time = self.sim_time
        )
    
    def get_lorenz_curve(self):
        pts = np.empty((self.num_points, 3))
        x,y,z = pts[0] = self.pos 
        dt = self.sim_time/self.num_points 

        for i in range(1, self.num_points):
            x_dot, y_dot, z_dot = self.update_curve(pos=(x,y,z))
            x += x_dot*dt
            y += y_dot*dt
            z += z_dot*dt
            pts[i] = np.array([x,y,z])

        curve = ParametricCurve(
            t_func=lambda i: pts[i],
            t_range=[0, self.num_points-1, 1]
        ).set_flat_stroke(False)
        return curve
    
    def update_curve(self, t=None, pos=None):
        x, y, z = pos 
        a, b, c = self.constants 
        x_dot = a*(y-x)
        y_dot = x*(b-z)-y 
        z_dot = x*y - c*z 
        return np.array([x_dot, y_dot, z_dot])
    

class ImprovedLorenzAttractorScene(LorenzAttractorScene):
    def get_lorenz_curve(self):
        dt = self.sim_time/self.num_points

        solution = solve_ivp(
            fun = self.update_curve,
            t_span=(.0, self.sim_time),
            y0=self.pos, 
            dense_output=True
        )

        curve = ParametricCurve(
            t_func=lambda t:solution.sol(t),
            t_range=(0, self.sim_time, dt)
        ).set_flat_stroke(False)

        return curve 
    
    # 扩展
    # .x = \sigma*(y-x)
    # .y = x*(\beta-z)-y
    # .z = x*y-\gamma*x 

    # .x = -y-z
    # .y = x+ay
    # .z = b+z(x-c)

    # .x = x(z-b)-yd
    # .y = xd+y(z-b)
    # .z = c+az +(z^3)/3+((x^2)+(y^2))(1+ez)+fz(x^3)


    # .x = -ax-4(y+z)-y^2
    # .y = -ay-4(z+x)-z^2
    # .z = -az-4(x+y)-x^2

# 窗口交互
# f - 移动frame
# d - 3d 旋转
# r - reset 重置
# s - select 选择
# u - unselect 取消选择
# g - 移动选择
# h - 水平移动
# v - 垂直移动
# i - 光标所在位置

# self.embed()
# manimgl my_script.py SceneName -e 
# 

class InteractiveManim(InteractiveScene):
    def construct(self):
        square = Square() 
        self.play(ShowCreation(square))
        self.wait()

        text = Text('this is a Square')
        text.next_to(square, DOWN, buff=.5)
        self.play(Write(text))
        self.wait()

class InteractiveManim2(InteractiveScene):
    def on_mouse_press(self, point, button, mods):
        LEFT_BUTTON = 1
        RIGHT_BUTTON = 4
        SHIFT_MODIFIER=1
        CTRL_MODIFIRE=2
        COMMAND_MODIFIER=64
        if button == LEFT_BUTTON:
            self.add(Dot(point))
        else:
            square = Square(side_length=1)
            square.set_color(RED_B, opacity=1)
            square.move_to(point)
            self.add(square)
        # return super().on_mouse_press(point, button, mods)

    def on_mouse_drag(self, point, d_point, buttons, mods):
        self.add(Dot(point))
    
    def on_mouse_release(self, point, button, mods):
        last_mobject = self.mobjects[-1]
        self.play(
            last_mobject.animate.set_width(2)
            .set_color(BLUE)
        )
    # 扩展
    # on_mouse_motion
    # on_mouse_scroll

    # 键盘事件

    def on_key_press(self, symbol, modifiers):
        char = chr(symbol)
        if char == ' ':
            self.text = Text('write_your_text_here')
            self.play(Write(self.text))
    def on_key_release(self, symbol, mods):
        char = chr(symbol)

        if char == ' ':
            new_text = Text('transformed_text')
            self.play(
                TransformMatchingStrings(self.text, new_text)
            )
            self.wait(2)
            self.play(FadeOut(new_text))
    

# GLSL 着色器作画
# Mobject.get_points() -> Mobject.data['point']

# sq = Square()
# sq.data
# sq.data.dtype
# 这些数据最终回放在 vert.glsl 和 frag.glsl 中 

# 着色器目录结构
# shader_folder = 'my_first_shader'
# shader_tutorial/
#   shader_tutorial.py
#   my_first_shader/
#       vert.glsl
#       frag.glsl
# ------或者-------
# shader_folder = None
# shader_tutorial/
#   shader_tutorial.py
#   SceneName/
#       vert.glsl
#       frag.glsl

# class ShaderDemonstration(ShaderScene):
#     shader_folder = 'my_first_shader'
#     def construct(self):
#         # this is to enable embed mode 
#         # or use self.embed()
#         pass 

# # ------ frag.glsl
'''

#version 330
in vec3 xyz_coords;
out vec4 frag_color;
void main(){
    frag_color = vec4(0.0, 0.0, 1.0, 0.5);
}

'''

# self.refresh_shader()
# self.refresh_and_hold()

# # ------ vert.glsl
'''
#version 330
inc vec3 point;
out vec3 xyz_coords;
#INSERT emit_gl_Position.glsl

void main() {
    xyz_coords = point;
    emit_gl_Position(point);
}

'''


'''
1、 Α α alpha a:lf 阿尔法 角度；系数
2 、Β β beta bet 贝塔 磁通系数；角度；系数
3、 Γ γ gamma ga:m 伽马 电导系数（小写）
4、 Δ δ delta delt 德尔塔 变动；根的判别式；屈光度
5、 Ε ε epsilon ep`silon 伊普西龙 对数之基数
6、 Ζ ζ zeta zat 截塔 系数；方位角；阻抗；相对粘度；原子序数
7、 Η η eta eit 艾塔 磁滞系数；效率（小写）
8、 Θ θ thet θit 西塔 温度；相位角
9、 Ι ι iot aiot 约塔 微小，一点儿
10、 Κ κ kappa kap 卡帕 介质常数
11、 ∧ λ lambda lambd 兰布达波长（小写）；体积
12、 Μ μ mu mju 缪 磁导系数；微（千分之一）；放大因数，摩擦系数（小写）
13、 Ν ν nu nju 纽 磁阻系数
14、 Ξ ξ xi ksi 克西
15、 Ο ο omicron omik`ron 奥密克戎
16、 ∏ π pi pai 派 圆周率=圆周÷直径=3.1416
17、 Ρ ρ rho rou 肉 电阻系数，密度（小写）
18、 ∑ σ sigma `sigma 西格马 总和（大写），表面密度；跨导（小写）
19、 Τ τ tau tau 套 时间常数
20、 Υ υ upsilon jup`silon 宇普西龙 位移
21、 Φ φ phi fai 佛爱 磁通；角
22、Χ χ chi phai 西
23、 Ψ ψ psi psai 普西 角速；介质电通量（静电力线）；角
24、 Ω ω omega o`miga 欧米伽 欧姆（大写，电阻）；角速（小写）；角
'''

